//一、请说出下列最终的执行结果，并解释为什么。
// var a = [];
// for (var i = 0; i < 10; i++) {
// 	a[i] = function () {
// 		console.log(i);
// 	};
// }
// a[6]();

// 答：10 因为for循环中的i使用var 声明之后就是一个全局的变量，即变成window对象下的变量。循环中a[i]是一个匿名方法，此匿名方法中的console.log(i)的是window下的i变量，每次遍历时变量i都会增加。数组a中的成员里面的i，指向的都是同一个i，导致运行时输出的是最后一轮的i的值

//二、请说出下列最终的执行结果，并解释为什么。
// var tmp = 123;
// if (true) {
//   console.log(tmp)
//   let tmp
// }

// 答：ReferenceError: tmp is not defined  原因：TDZ

// 三、结合ES6新语法，用最简单的方法找出数组中的最小值。
// var arr = [12, 34, 32, 89, 4]
// 答：console.log(Math.min(...arr))

// 四、请详细说明var，let，const三种声明变量的方式之间的具体差别。
// var 没有块级作用域，支持变量提升
// let 有块级作用域，不支持变量提升。不允许重复声明，暂存性死区。不能通过window.变量名进行访问
// const 有块级作用域，不支持变量提升，不允许重复声明，暂存性死区。声明一个变量一旦声明，变量的引用就不能被更改，改变报错

// 五、请说出下列代码最终输出的结果，并解释为什么。
// var a = 10;
// var obj = {
// 	a: 20,
// 	fn() {
// 		setTimeout(() => {
// 			console.log(this.a);
// 		});
// 	}
// };
// obj.fn();
// 答：20  首先通过obj调用fn函数，在fn函数内部this的指向是obj。而setTimeout中的箭头函数是没有this的指向的，里面的this依赖于上层作用域中的this，即obj。所以这里的console.log(this.a) 输出20

// 六、简述symbol类型的用途。
// Symbol的作用就是表示一个独一无二的值，我们通过Symbol创建的每一个值都是独一无二的，永远不会重复。
// 考虑到开发过程中的调试，Symbol允许传入一个字符串作为这个值的描述文本。它除了可以避免对象属性名重复产生的问题，我们还可以借助这种类型的特点模拟对象的私有成员。通过Symbol创建的值一定是一个唯一的值，不管传入的描述文本是否相同。
// 使用Symbol类型提供的静态方法for()在全局去复用一个相同的Symbol值。这个方法内部维护了一个全局的注册表，为字符串和Symbol值提供了一一对应的关系。如果传入的不是字符串，方法内部会将其自动转化为字符串。除了定义自己使用的Symbol值以外，ES2015还提供了11个内置Symbol值，指向语言内部使用的方法。 Object对象里面的getOwnPropertySymbols()方法可以获取到Symbol类型的属性名。

// 七、什么是浅拷贝？什么是深拷贝？
// 浅拷贝：复制对象的引用，不复制对象本身。当其中一个对象属性更改时，另一个也会改变。
// 浅拷贝实现：引用赋值、ES6扩展运算符 … 、Object.assign
// 深拷贝：复制对象本身。当其中一个对象属性更改时，另一个不会改变。
// 深拷贝实现：object.assgin()、JSON.parse(JSON.stringify())、递归的方式

// 八、请简述TypeScript与JavaScript之间的关系。
// JS是弱类型语言，变量的声明可以随意更改。TS是JS的超集，是对JS的增强。

// 九、请谈谈你所认为的TypeScript优缺点
// 优点：增加代码可维护性、兼容JS语法、减少不必要的类型的判断
// 缺点：增加学习成本、开发成本、与一些库可能不兼容

// 十、描述引用计数的工作原理和优缺点。
// 通过一个变量来对引用的变量进行计数，初始值为0，每次引用时增加1，断开引用时减1，当引用计数为0时回收变量。
// 优点：发现垃圾时立即回收、最大限度减少程序暂停
// 缺点：空间的浪费（增加引用计数的变量）、时间开销大、无法回收循环引用的对象

// 十一、描述标记整理算法的工作流程。
// 首先遍历所有对象，将不可达对象进行标记。然后在清除阶段将所有标记为不可达的对象空间进行回收，将所有可达对象进行整理，把可达对象放到连续的内存空间。

// 十二、描述V8中新生代存储区垃圾回收的流程。
// V8将新生代中的空间一分为二。使用的空间为From，空闲的空间为To。活动对象存在From空间中，标记整理后将活动对象拷贝到To，From和To交换空间完成释放。

// 十三、描述增量标记算法在何时使用及工作原理。
// GC的执行需要暂停程序的执行。V8 新生代的垃圾回收中，因其空间较小，且存活对象较少，所以全停顿的影响不大；V8 老年代的垃圾回收中，为了降低老生代的垃圾回收而造成的卡顿，使用增量标记算法。增量标记算法分为一个个的子标记过程，让垃圾回收标记和 JavaScript 应用逻辑交替进行，小的垃圾回收任务执行时间比较短，最大限度减少程序暂停时间。标记完后执行清除，程序继续执行
